﻿unit SysNormalRoleRightService;

interface
{$I ../Config.inc}
uses
  FastMM4,
  FastMove,
  System.SysUtils,
  System.Classes,
  System.Types,
  Winapi.Windows,
  Data.DB,
  Data.Win.ADODB,
  Datasnap.DBClient,
  Datasnap.Provider,
  {$IFDEF UNICODE}
  AnsiStrings,
  {$ENDIF }
  QBParcel,
  DllSpread,
  Generics.Collections,
  DateUtils,
  QJson,
  UserConnection,
  DBAccessor,
  DllPlugin,
  StrUtils,
  SKSOFTComm,
  SysNormalRoleRightModel,
  SysNormalRoleRightBLL,
  SysRightRegisterModel;
  
type

  TSysNormalRoleRightService = class(TSysNormalRoleRightBLL)
  private

  protected

  public
  {$IFDEF SERVER}
    function BeforeTreatment(const iItem:TSysNormalRoleRight; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
    function BeforeTreatment(const iItems:TSysNormalRoleRightList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;

    function BeforeCheck(const iItem:TSysNormalRoleRight; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
    function BeforeCheck(const iItems:TSysNormalRoleRightList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;

    function Check(const iItem:TSysNormalRoleRight; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
    function Check(const iItems:TSysNormalRoleRightList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;

    function BeforeExecute(const iItem:TSysNormalRoleRight; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
    function BeforeExecute(const iItems:TSysNormalRoleRightList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;

    function AfterTreatment(const iItem:TSysNormalRoleRight; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
    function AfterTreatment(const iItems:TSysNormalRoleRightList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
  {$ENDIF}

    class function NormalRightStrToObj(const iRightRegisterItemCds:TClientDataSet; const iNormalRightItem:TSysNormalRoleRight;
                                const oModuleIdList,oGroupIdList,oMenuList,oComponentList:TStringList):Boolean;overload;
    class function NormalRightStrToObj(const iRightRegisterItemCds:TClientDataSet; const iNormalRightList:TSysNormalRoleRightList;
                                const oModuleIdList,oGroupIdList,oMenuList,oComponentList:TStringList):Boolean;overload;

    class function RightRegisterListToNormalRightStr(const iRightRegisterList:TSysRightRegisterList):string;
    class function RightRegisterListToObj(const iRightRegisterList:TSysRightRegisterList;
                                const oModuleIdList,oGroupIdList,oMenuList,oComponentList:TStringList):Boolean;

    function LoadByRoleId(const iRoleId:string; const iRightRegisterItemCds:TClientDataSet; const oNormalRightItem:TSysNormalRoleRight;
                          const oModuleIdList,oGroupIdList,oMenuList,oComponentList:TStringList; out oError:string):Boolean;
    function LoadByRoleIds(const iRoleIds:TStrings; const iRightRegisterItemCds:TClientDataSet; const oNormalRightList:TSysNormalRoleRightList;
                          const oModuleIdList,oGroupIdList,oMenuList,oComponentList:TStringList; out oError:string):Boolean;
  end;
  
implementation

{$IFDEF SERVER}
function TSysNormalRoleRightService.BeforeTreatment(const iItem:TSysNormalRoleRight; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
var
  ItemDB:TSysNormalRoleRight;
begin
  if iItem<>nil then
  begin
    ItemDB:=TSysNormalRoleRight.Create;
    try
      case iPreMode of
      pmAdd:
        begin
          iItem.Id:=iItem.ObjGUID;
        end;
      pmEdit:
        begin
          if not iParcel.GoodsExists(AnsiString(iItem.ClassName)) then
          begin
            if ItemDB.LoadFromStr(iItem.SaveToStr,oError) and
              Reload(ItemDB,oError) then
            begin
              iParcel.PutStringGoods(AnsiString(iItem.ClassName),ItemDB.SaveToStr);
            end else begin
              oError:=Format(string('调用%s.BeforeTreatment错误 --> %s'),[Self.ClassName,oError]);
              Result:=False;
              Exit;
            end;
          end else if not ItemDB.LoadFromStr(iParcel.GetStringGoods(AnsiString(iItem.ClassName)),oError) then
          begin
            oError:=Format(string('调用%s.BeforeTreatment错误 --> %s'),[Self.ClassName,oError]);
            Result:=False;
            Exit;
          end;
        end;
      pmDelete:
        begin
          if not Reload(iItem,oError) then
          begin
            oError:=Format(string('调用%s.BeforeTreatment错误 --> %s'),[Self.ClassName,oError]);
            Result:=False;
            Exit;
          end;
        end;
      end;
    finally
      FreeAndNil(ItemDB);
    end;
  end else begin
    oError:=Format(string('调用%s.BeforeTreatment错误...错误内容:传入的对象或字符串为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysNormalRoleRightService.BeforeTreatment(const iItems:TSysNormalRoleRightList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysNormalRoleRightService.BeforeCheck(const iItem:TSysNormalRoleRight; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysNormalRoleRightService.BeforeCheck(const iItems:TSysNormalRoleRightList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysNormalRoleRightService.Check(const iItem:TSysNormalRoleRight; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
var
  ItemDB:TSysNormalRoleRight;
begin
  if iItem<>nil then
  begin
    ItemDB:=TSysNormalRoleRight.Create;
    try
      if SameStr(Trim(iItem.Id),EmptyStr) then
      begin
        oError:='ID不允许为空';
        Result:=False;
        Exit;
      end else if SameStr(Trim(iItem.RoleId),EmptyStr) then
      begin
        oError:='角色ID不允许为空';
        Result:=False;
        Exit;
      end else if SameStr(Trim(iItem.OwnRightStr),EmptyStr) then
      begin
        oError:='权限内容不允许为空';
        Result:=False;
        Exit;
      end;

      case iPreMode of
      pmAdd:
        begin
        end;
      pmEdit:
        begin
          if not iParcel.GoodsExists(AnsiString(iItem.ClassName)) then
          begin
            if ItemDB.LoadFromStr(iItem.SaveToStr,oError) and
              Reload(ItemDB,oError) then
            begin
              iParcel.PutStringGoods(AnsiString(iItem.ClassName),ItemDB.SaveToStr);
            end else begin
              oError:=Format(string('调用%s.Check错误 --> %s'),[Self.ClassName,oError]);
              Result:=False;
              Exit;
            end;
          end else if not ItemDB.LoadFromStr(iParcel.GetStringGoods(AnsiString(iItem.ClassName)),oError) then
          begin
            oError:=Format(string('调用%s.Check错误 --> %s'),[Self.ClassName,oError]);
            Result:=False;
            Exit;
          end;
          if not SameStr(Trim(iItem.RoleId),Trim(ItemDB.RoleId)) then
          begin
            oError:='角色ID不允许修改';
            Result:=False;
            Exit;
          end else if iItem.TimeStamp<>ItemDB.TimeStamp then
          begin
            oError:='权限信息已被他人修改，请重新装载...';
            Result:=False;
            Exit;
          end;
        end;
      pmDelete:
        begin
        end;
      end;
    finally
      FreeAndNil(ItemDB);
    end;
  end else begin
    oError:=Format(string('调用%s.Check错误...错误内容:传入的对象或字符串为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysNormalRoleRightService.Check(const iItems:TSysNormalRoleRightList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysNormalRoleRightService.BeforeExecute(const iItem:TSysNormalRoleRight; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  if iItem<>nil then
  begin
    case iPreMode of
    pmAdd:
      begin
        iItem.TimeStamp:=TSKSOFTComm.GetTimeStampMs;
      end;
    pmEdit:
      begin
        iItem.TimeStamp:=TSKSOFTComm.GetTimeStampMs;
      end;
    pmDelete:
      begin
      end;
    pmUse:
      begin
      end;
    pmUnUse:
      begin
      end;
    end;
  end else begin
    oError:=Format(string('调用%s.BeforeExecute错误...错误内容:传入的对象或字符串为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysNormalRoleRightService.BeforeExecute(const iItems:TSysNormalRoleRightList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysNormalRoleRightService.AfterTreatment(const iItem:TSysNormalRoleRight; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysNormalRoleRightService.AfterTreatment(const iItems:TSysNormalRoleRightList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;
{$ENDIF}

class function TSysNormalRoleRightService.NormalRightStrToObj(const iRightRegisterItemCds:TClientDataSet; const iNormalRightItem:TSysNormalRoleRight;
                                                  const oModuleIdList,oGroupIdList,oMenuList,oComponentList:TStringList):Boolean;

procedure Calculate(const iRightItemsArray:TQJson);
var
  Index,Index1,Deep:Integer;
  RightRegisterGuid,RightRegisterId,RightRegisterPid:string;
  Filter:string;
begin
  for Index := 0 to iRightItemsArray.Count-1 do
  begin
    RightRegisterGuid:=iRightItemsArray.Items[Index].AsString;
    Filter:=Format(string('%s=''%s'''),[TSysRightRegisterModel.cRightIdKey,RightRegisterGuid]);
    iRightRegisterItemCds.Filter:=Filter;
    iRightRegisterItemCds.Filtered:=True;
    Deep:=iRightRegisterItemCds.FieldByName(TSysRightRegisterModel.cRightDeepKey).AsInteger;
    for Index1:=Deep downto 1 do
    begin
      if Index1=Deep then
      begin
        Filter:=Format(string('%s=''%s'''),[TSysRightRegisterModel.cRightIdKey,RightRegisterGuid]);
      end else begin
        Filter:=Format(string('%s=''%s'''),[TSysRightRegisterModel.cRightTreeIdKey,RightRegisterPid]);
      end;
      iRightRegisterItemCds.Filter:=Filter;
      iRightRegisterItemCds.Filtered:=True;
      if (iRightRegisterItemCds.RecordCount=1) then
      begin
        if not SameStr(iRightRegisterItemCds.FieldByName(TSysRightRegisterModel.cRightTreePidKey).AsString,EmptyStr) then
        begin
          RightRegisterGuid:=iRightRegisterItemCds.FieldByName(TSysRightRegisterModel.cRightIdKey).AsString;
          RightRegisterId:=iRightRegisterItemCds.FieldByName(TSysRightRegisterModel.cRightTreeIdKey).AsString;
          RightRegisterPid:=iRightRegisterItemCds.FieldByName(TSysRightRegisterModel.cRightTreePidKey).AsString;
          case Index1 of
          4:begin
              if (oComponentList<>nil) then
              begin
                oComponentList.Add(RightRegisterGuid);
              end;
            end;
          3:begin
              if (oMenuList<>nil) then
              begin
                oMenuList.Add(RightRegisterGuid);
              end;
            end;
          2:begin
              if (oGroupIdList<>nil) then
              begin
                oGroupIdList.Add(RightRegisterGuid);
              end;
            end;
          1:begin
              if (oModuleIdList<>nil) then
              begin
                oModuleIdList.Add(RightRegisterGuid);
              end;
            end;
          end;
        end else if iRightRegisterItemCds.FieldByName(TSysRightRegisterModel.cRightDeepKey).AsInteger=1 then
        begin
          Exit;
        end else begin
          Exit;
        end;
      end else begin
        Exit;
      end;
    end;
  end;
end;

var
  Json,RightItemsArray:TQJson;
begin
  if (iRightRegisterItemCds<>nil) and (iNormalRightItem<>nil) then
  begin
    if (oModuleIdList<>nil) then
    begin
      oModuleIdList.Duplicates := dupIgnore;
    end;
    if (oGroupIdList<>nil) then
    begin
      oGroupIdList.Duplicates := dupIgnore;
    end;
    if (oMenuList<>nil) then
    begin
      oMenuList.Duplicates := dupIgnore;
    end;
    if (oComponentList<>nil) then
    begin
      oComponentList.Duplicates := dupIgnore;
    end;

    Json:=TQJson.Create;
    try
      if Json.TryParse(iNormalRightItem.OwnRightStr) then
      begin
        if (Json.ItemByName('module_items')<>nil) and
          (Json.ItemByName('module_items').IsArray) then
        begin
          RightItemsArray:=Json.ItemByName('module_items');
          Calculate(RightItemsArray);
        end;
        if (Json.ItemByName('group_items')<>nil) and
          (Json.ItemByName('group_items').IsArray) then
        begin
          RightItemsArray:=Json.ItemByName('group_items');
          Calculate(RightItemsArray);
        end;
        if (Json.ItemByName('menu_items')<>nil) and
          (Json.ItemByName('menu_items').IsArray) then
        begin
          RightItemsArray:=Json.ItemByName('menu_items');
          Calculate(RightItemsArray);
        end;
        if (Json.ItemByName('component_items')<>nil) and
          (Json.ItemByName('component_items').IsArray) then
        begin
          RightItemsArray:=Json.ItemByName('component_items');
          Calculate(RightItemsArray);
        end;
      end else begin
        Result:=True;
        Exit;
      end;
    finally
      Json.Free;
    end;
  end else begin
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

class function TSysNormalRoleRightService.NormalRightStrToObj(const iRightRegisterItemCds:TClientDataSet; const iNormalRightList:TSysNormalRoleRightList;
                                                const oModuleIdList,oGroupIdList,oMenuList,oComponentList:TStringList):Boolean;
var
  Key:string;
begin
  if iNormalRightList<>nil then
  begin
    for Key in iNormalRightList.SortKeys do
    begin
      if not NormalRightStrToObj(iRightRegisterItemCds,iNormalRightList.Items[Key],
                          oModuleIdList,oGroupIdList,oMenuList,oComponentList) then
      begin
        Result:=False;
        Exit;
      end;
    end;
  end else begin
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

class function TSysNormalRoleRightService.RightRegisterListToNormalRightStr(const iRightRegisterList:TSysRightRegisterList):string;
var
  Json,ModuleItems,GroupItems,MenuItems,ComponentItems:TQJson;
  Key:string;
begin
  Json:=TQJson.Create;
  try
    ModuleItems:=Json.Add('module_items',jdtArray);
    GroupItems:=Json.Add('group_items',jdtArray);
    MenuItems:=Json.Add('menu_items',jdtArray);
    ComponentItems:=Json.Add('component_items',jdtArray);
    if iRightRegisterList<>nil then
    begin
      for Key in iRightRegisterList.SortKeys do
      begin
        case iRightRegisterList.Items[Key].RightDeep of
        0:begin//根节点无意义

          end;
        1:begin //模块
            ModuleItems.Add('items',Key);
          end;
        2:begin //分组
            GroupItems.Add('items',Key);
          end;
        3:begin //菜单
            MenuItems.Add('items',Key);
          end;
        4:begin //组件
            ComponentItems.Add('items',Key);
          end;
        end;
      end;
    end;
    Result:=Json.AsString;
  finally
    Json.Free;
  end;
end;

class function TSysNormalRoleRightService.RightRegisterListToObj(const iRightRegisterList:TSysRightRegisterList;
                                const oModuleIdList,oGroupIdList,oMenuList,oComponentList:TStringList):Boolean;
var
  Key:string;
begin
  if (oModuleIdList<>nil) then
  begin
    oModuleIdList.Duplicates := dupIgnore;
  end;
  if (oGroupIdList<>nil) then
  begin
    oGroupIdList.Duplicates := dupIgnore;
  end;
  if (oMenuList<>nil) then
  begin
    oMenuList.Duplicates := dupIgnore;
  end;
  if (oComponentList<>nil) then
  begin
    oComponentList.Duplicates := dupIgnore;
  end;
  if iRightRegisterList<>nil then
  begin
    for Key in iRightRegisterList.SortKeys do
    begin
      case iRightRegisterList.Items[Key].RightDeep of
      0:begin//根节点无意义

        end;
      1:begin //模块
          if (oModuleIdList<>nil) then
          begin
            oModuleIdList.Add(Key);
          end;
        end;
      2:begin //分组
          if (oGroupIdList<>nil) then
          begin
            oGroupIdList.Add(Key);
          end;
        end;
      3:begin //菜单
          if (oMenuList<>nil) then
          begin
            oMenuList.Add(Key);
          end;
        end;
      4:begin //组件
          if (oComponentList<>nil) then
          begin
            oComponentList.Add(Key);
          end;
        end;
      end;
    end;
  end;
  Result:=True;
end;

function TSysNormalRoleRightService.LoadByRoleId(const iRoleId:string; const iRightRegisterItemCds:TClientDataSet; const oNormalRightItem:TSysNormalRoleRight;
                      const oModuleIdList,oGroupIdList,oMenuList,oComponentList:TStringList; out oError:string):Boolean;
var
  Condition:string;
begin
  if (not SameStr(iRoleId,EmptyStr))
    and (iRightRegisterItemCds<>nil)
    and (oNormalRightItem<>nil)
    and (oModuleIdList<>nil)
    and (oGroupIdList<>nil)
    and (oMenuList<>nil)
    and (oComponentList<>nil) then
  begin
    Condition:=Format(string('%s=''%s'''),[TSysNormalRoleRightModel.cRoleIdKey,iRoleId]);
    if not LoadByCondition(oNormalRightItem,Condition,oError) then
    begin
      Result:=False;
      Exit;
    end;

    if not TSysNormalRoleRightService.NormalRightStrToObj(iRightRegisterItemCds,oNormalRightItem,
                                                          oModuleIdList,oGroupIdList,
                                                          oMenuList,oComponentList) then
    begin
      Result:=False;
      Exit;
    end;

  end else begin
    oError:=Format(string('调用TSysNormalRoleRightService.LoadByRoleId方法失败！错误内容:传入的iRoleId或iRightRegisterItemCds或oNormalRightItem或oModuleIdList或oGroupIdList或oMenuList或oComponentList为空!'),[]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysNormalRoleRightService.LoadByRoleIds(const iRoleIds:TStrings; const iRightRegisterItemCds:TClientDataSet; const oNormalRightList:TSysNormalRoleRightList;
                      const oModuleIdList,oGroupIdList,oMenuList,oComponentList:TStringList; out oError:string):Boolean;
var
  RoleId,RoleIds,Condition,OrderBy:string;
begin
  if (iRoleIds<>nil)
    and (iRightRegisterItemCds<>nil)
    and (oNormalRightList<>nil)
    and (oModuleIdList<>nil)
    and (oGroupIdList<>nil)
    and (oMenuList<>nil)
    and (oComponentList<>nil) then
  begin
    RoleIds:=EmptyStr;
    for RoleId in iRoleIds do
    begin
      RoleIds:=RoleIds+''''+RoleId+''',';
    end;

    if RoleIds.Length>0 then
    begin
      RoleIds:=LeftStr(RoleIds,RoleIds.Length-1);
      Condition:=Format(string('%s IN (%s)'),[TSysNormalRoleRightModel.cRoleIdKey,RoleIds]);
      OrderBy:=TSysNormalRoleRightModel.cRoleIdKey+' ASC';
      if not LoadByCondition(oNormalRightList,Condition,oError,OrderBy) then
      begin
        Result:=False;
        Exit;
      end;
    end;
    if not TSysNormalRoleRightService.NormalRightStrToObj(iRightRegisterItemCds,oNormalRightList,
                                                        oModuleIdList,oGroupIdList,
                                                        oMenuList,oComponentList) then
    begin
      Result:=False;
      Exit;
    end;
  end else begin
    oError:=Format(string('调用TSysNormalRoleRightService.LoadByRoleIds方法失败！错误内容:传入的iRoleId或iRightRegisterItemCds或oNormalRightItem或oModuleIdList或oGroupIdList或oMenuList或oComponentList为空!'),[]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;
  
end.
